package com.sofwin.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.sofwin.mapper.SResourceMapper;
import com.sofwin.mapper.SRoleMapper;
import com.sofwin.mapper.SRoleResourceMapper;
import com.sofwin.pojo.*;
import com.sofwin.service.SRoleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class SRoleServiceImpl implements SRoleService {
    @Autowired
    private SRoleMapper mapper;
    @Autowired
    private SResourceMapper resourceMapper;
    @Autowired
    private SRoleResourceMapper roleResourceMapper;
    @Override
    public List<SRole> getRoleNames() {
        return mapper.selectByExample(null);
    }

    @Override
    public PageInfo<SRole> selectRoleByPage(SRole role, Integer pageNum, Integer pageSize) {
        SRoleExample example = new SRoleExample();
        SRoleExample.Criteria criteria = example.createCriteria();
        if (role!=null) {
            if (role.getRoleName() != null && !"".equals(role.getRoleName())) {
                criteria.andRoleNameLike("%" + role.getRoleName() + "%");
            }
            if (role.getFlag() != null) {
                criteria.andFlagEqualTo(role.getFlag());
            }
        }
        PageHelper.startPage(pageNum,pageSize);
        List<SRole> sRoles = mapper.selectByExample(example);
        return new PageInfo<SRole>(sRoles);
    }

    @Override
    public boolean deleteRoles(Integer[] ids) {
        int flag = 0;
        SRoleKey key = null;
        for (Integer id:ids) {
            key = new SRoleKey();
            key.setId(id);
            flag+=mapper.deleteByPrimaryKey(key);
        }
        return flag==ids.length?true:false;
    }

    @Override
    public SRole selectById(Integer id) {
        SRoleKey key = new SRoleKey();
        key.setId(id);
        return mapper.selectByPrimaryKey(key);
    }

    @Override
    public boolean insertRole(SRole role) {
        if (role.getId()!=null){
            // 更新
            return mapper.updateByPrimaryKeySelective(role)==1?true:false;
        }
        return mapper.insertSelective(role)==1?true:false;
    }

    @Override
    public boolean savePermission1(Integer roleId, Integer[] resourceIds) {
        boolean status = false;
        int flag = 0;
        // 先删除 该角色的所有role-resource
        SRoleResourceExample example = new SRoleResourceExample();
        SRoleResourceExample.Criteria criteria = example.createCriteria();
        criteria.andRoleIdEqualTo(roleId);
        roleResourceMapper.deleteByExample(example);
        // 再插入 被选中的资源
        for (Integer resourceId:resourceIds) {
            SRoleResource roleResource = new SRoleResource();
            roleResource.setRoleId(roleId);
            roleResource.setResourceId(resourceId);
            flag+=roleResourceMapper.insertSelective(roleResource);
        }
        // 可能就点开看一看
        if (resourceIds == null || resourceIds.length == 0){
            status = true;
        }else if (flag == resourceIds.length){
            status = true;
        }
        return status;
    }


    public boolean savePermission(boolean isChecked, Integer roleId, Integer resourceId) {
        SResourceKey key = new SResourceKey();
        key.setId(resourceId);
        // 当前资源
        SResource currResource = resourceMapper.selectByPrimaryKey(key);
        boolean status = false;
        // 1、判断 勾选|取消勾选
        if (isChecked){
            // 2、勾选操作
            // 是否为父节点
            if (isParentNode(resourceId)){
                status = saveParentAndAllChildren(roleId,resourceId);
            }else {
                // 是否为第一个子节点
                if (isFirstChildrenNode(roleId,resourceId)){
                    // 保存父节点,👇保存第一个子节点
                    status = saveRoleResource(roleId,currResource.getParentId());
                }
                status = saveRoleResource(roleId,resourceId);
            }
        }else {
            // 3、取消勾选
            // 是否为父节点
            if (isParentNode(resourceId)){
                // 删除父+子节点
                status = deleteParentAndAllChildren(roleId,resourceId);
            }else {
                // 是否为最后一个子节点
                if (isLastChildrenNode(roleId,resourceId)){
                    // 删除本节点+父节点
                    status = deleteParentAndAllChildren(roleId,currResource.getParentId());
                }else {
                    status = deleteRoleResourceByResourceId(roleId,resourceId);
                }
            }
        }
        return status;
    }

    private boolean deleteRoleResourceByResourceId(Integer roleId, Integer resourceId) {
        SRoleResourceExample example = new SRoleResourceExample();
        SRoleResourceExample.Criteria criteria = example.createCriteria();
        criteria.andRoleIdEqualTo(roleId);
        criteria.andResourceIdEqualTo(resourceId);
        int num = roleResourceMapper.deleteByExample(example);
        return num==1?true:false;
    }

    /**
     * 判断是否为最后一个子节点
     * @param resourceId
     * @return
     */
    private boolean isLastChildrenNode(Integer roleId,Integer resourceId) {
        int num = roleResourceMapper.selectIsLastChildrenNode(roleId,resourceId);
        return num==1?true:false;
    }

    /**
     * 删除本身父节点+所有子节点
     * @param roleId
     * @param resourceId
     * @return
     */
    private boolean deleteParentAndAllChildren(Integer roleId, Integer resourceId) {
        int num = roleResourceMapper.deleteParentAndAllChildren(roleId, resourceId);
        return num>0?true:false;
    }

    /**
     * 插入父节点
     * @param roleId
     * @param parentId
     * @return
     */
    private boolean saveRoleResource(Integer roleId, Integer parentId) {
        SRoleResource roleResource = new SRoleResource();
        roleResource.setRoleId(roleId);
        roleResource.setResourceId(parentId);
        int num = roleResourceMapper.insertSelective(roleResource);
        return num==1?true:false;
    }

    /**
     * 是否是 勾选 的第一个子节点
     * @param roleId
     * @param resourceId
     * @return
     */
    private boolean isFirstChildrenNode(Integer roleId, Integer resourceId) {
        // 是否有该子节点的父节点在数据库R_S中
        int num = roleResourceMapper.selectIsExistParentByresourceId(roleId,resourceId);
        return num==1?false:true;
        // 或者逆向工程 自定义条件查询
    }

    /**
     * 插入父＋子
     * @param roleId
     * @param resourceId
     * @return
     */
    private boolean saveParentAndAllChildren(Integer roleId, Integer resourceId) {
        int num = roleResourceMapper.saveParentAndAllChildren(roleId,resourceId);
        return num>0?true:false;
    }

    /**
     * 判断资源节点是否为父节点
     * @param resourceId
     * @return
     */
    private boolean isParentNode(Integer resourceId) {
        SResourceKey key = new SResourceKey();
        key.setId(resourceId);
        SResource sResource = resourceMapper.selectByPrimaryKey(key);
        return sResource.getParentId()==0?true:false;
    }
}
